package app

import (
    "net/http"
    "encoding/json"
    "io/ioutil"
)

// 保存 Request、Response 信息
type Context struct {
    Request *http.Request
    Writer http.ResponseWriter
    // 处理器
    handlers HandlersChain
    // 处理器下标
    index int8
    Params Params
    // 当前用户id
    Uid int
}

type Obj map[string]interface{}

var contentTypeJson = "application/json; charset=utf-8"

// 执行下一个方法
func (c *Context) Next()  {
    c.index++
    if n := int8(len(c.handlers)); c.index < n {
        c.handlers[c.index](c)
    }
}

func (c *Context) Index() int8  {
    return c.index
}

// 返回 json 数据
func (c *Context) ResponseJson(code int, data interface{}) error  {
    obj := Obj{
        "code": code,
        "msg" : "success",
        "data": data,
    }
    jsonBytes, err := json.Marshal(obj)
    if err != nil {
        return err
    }

    c.SetContentType(contentTypeJson)
    c.Writer.WriteHeader(http.StatusOK)
    c.Writer.Write(jsonBytes)
    return nil
}

// 返回错误
func (c *Context) ErrorResponse (code int, msg string) error {
    obj := Obj{
        "code": code,
        "msg" : msg,
        "data": "",
    }
    jsonBytes, err := json.Marshal(obj)
    if err != nil {
        return err
    }

    c.SetContentType(contentTypeJson)
    c.Writer.WriteHeader(http.StatusOK)
    c.Writer.Write(jsonBytes)
    return nil
}
// 设置响应头
func (c *Context) SetContentType(value string)  {
    c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
    c.Writer.Header().Add("Access-Control-Allow-Headers", "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since,Token")
    c.Writer.Header().Set("Content-Type", value)
}

func (c *Context) Query(s string) string {
    value, _ := c.GetQuery(s)
    return value
}

func (c *Context) GetQuery(s string) (string, bool) {
    if values, ok := c.GetQueryArray(s); ok {
        return values[0], ok
    }
    return "", false
}

func (c *Context) GetQueryArray(key string) ([]string, bool) {
    if values, ok := c.Request.URL.Query()[key]; ok && len(values) > 0 {
        return values, true
    }
    return []string{}, false
}

func (c *Context) Param(key string) string {
    return c.Params.ByName(key)
}

func (c *Context) GetRawData(data interface{}) error  {
    body, err := ioutil.ReadAll(c.Request.Body)
    if err != nil {
        return err
    }
    err = json.Unmarshal(body, &data)
    if err != nil {
        return err
    }
    return nil
}